{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "from tensorflow.examples.tutorials.mnist import input_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting MNIST_data\\train-images-idx3-ubyte.gz\n",
      "Extracting MNIST_data\\train-labels-idx1-ubyte.gz\n",
      "Extracting MNIST_data\\t10k-images-idx3-ubyte.gz\n",
      "Extracting MNIST_data\\t10k-labels-idx1-ubyte.gz\n",
      "y1.shape\n",
      "(?, 28, 28, 4)\n",
      "(?, 14, 14, 4)\n",
      "y2.shape\n",
      "(?, 14, 14, 8)\n",
      "(?, 7, 7, 8)\n",
      "y3.shape\n",
      "(?, 7, 7, 12)\n",
      "(?, 4, 4, 12)\n",
      "y4.shape\n",
      "(?, 4, 4, 16)\n",
      "(?, 2, 2, 16)\n",
      "y5.shape\n",
      "(?, 2, 2, 20)\n",
      "(?, 1, 1, 20)\n",
      "(?, 200)\n",
      "(?, 10)\n",
      "train step is : 0\n",
      "0.0892\n",
      "train step is : 100\n",
      "0.1094\n",
      "train step is : 200\n",
      "0.1135\n",
      "train step is : 300\n",
      "0.1135\n",
      "train step is : 400\n",
      "0.1135\n",
      "train step is : 500\n",
      "0.1135\n",
      "train step is : 600\n",
      "0.1135\n",
      "train step is : 700\n",
      "0.1135\n",
      "train step is : 800\n",
      "0.1139\n",
      "train step is : 900\n",
      "0.1135\n",
      "train step is : 1000\n",
      "0.1141\n",
      "train step is : 1100\n",
      "0.144\n",
      "train step is : 1200\n",
      "0.1773\n",
      "train step is : 1300\n",
      "0.2077\n",
      "train step is : 1400\n",
      "0.3065\n",
      "train step is : 1500\n",
      "0.3805\n",
      "train step is : 1600\n",
      "0.4805\n",
      "train step is : 1700\n",
      "0.5032\n",
      "train step is : 1800\n",
      "0.65\n",
      "train step is : 1900\n",
      "0.6832\n",
      "train step is : 2000\n",
      "0.7497\n",
      "train step is : 2100\n",
      "0.7618\n",
      "train step is : 2200\n",
      "0.8241\n",
      "train step is : 2300\n",
      "0.8241\n",
      "train step is : 2400\n",
      "0.8508\n",
      "train step is : 2500\n",
      "0.8573\n",
      "train step is : 2600\n",
      "0.8863\n",
      "train step is : 2700\n",
      "0.8904\n",
      "train step is : 2800\n",
      "0.9147\n",
      "train step is : 2900\n",
      "0.9247\n",
      "train step is : 3000\n",
      "0.8995\n",
      "train step is : 3100\n",
      "0.9211\n",
      "train step is : 3200\n",
      "0.925\n",
      "train step is : 3300\n",
      "0.9357\n",
      "train step is : 3400\n",
      "0.935\n",
      "train step is : 3500\n",
      "0.9304\n",
      "train step is : 3600\n",
      "0.935\n",
      "train step is : 3700\n",
      "0.9365\n",
      "train step is : 3800\n",
      "0.9426\n",
      "train step is : 3900\n",
      "0.9377\n",
      "train step is : 4000\n",
      "0.9399\n",
      "train step is : 4100\n",
      "0.9475\n",
      "train step is : 4200\n",
      "0.9435\n",
      "train step is : 4300\n",
      "0.9519\n",
      "train step is : 4400\n",
      "0.9509\n",
      "train step is : 4500\n",
      "0.9465\n",
      "train step is : 4600\n",
      "0.9152\n",
      "train step is : 4700\n",
      "0.9495\n",
      "train step is : 4800\n",
      "0.9556\n",
      "train step is : 4900\n",
      "0.9532\n",
      "train step is : 5000\n",
      "0.9577\n",
      "train step is : 5100\n",
      "0.9557\n",
      "train step is : 5200\n",
      "0.9568\n",
      "train step is : 5300\n",
      "0.9591\n",
      "train step is : 5400\n",
      "0.9576\n",
      "train step is : 5500\n",
      "0.9537\n",
      "train step is : 5600\n",
      "0.9571\n",
      "train step is : 5700\n",
      "0.9581\n",
      "train step is : 5800\n",
      "0.9622\n",
      "train step is : 5900\n",
      "0.9635\n",
      "train step is : 6000\n",
      "0.9604\n",
      "train step is : 6100\n",
      "0.9625\n",
      "train step is : 6200\n",
      "0.954\n",
      "train step is : 6300\n",
      "0.9629\n",
      "train step is : 6400\n",
      "0.9638\n",
      "train step is : 6500\n",
      "0.956\n",
      "train step is : 6600\n",
      "0.9616\n",
      "train step is : 6700\n",
      "0.9649\n",
      "train step is : 6800\n",
      "0.9647\n",
      "train step is : 6900\n",
      "0.9637\n",
      "train step is : 7000\n",
      "0.9635\n",
      "train step is : 7100\n",
      "0.9637\n",
      "train step is : 7200\n",
      "0.9669\n",
      "train step is : 7300\n",
      "0.9663\n",
      "train step is : 7400\n",
      "0.9666\n",
      "train step is : 7500\n",
      "0.9683\n",
      "train step is : 7600\n",
      "0.9617\n",
      "train step is : 7700\n",
      "0.9672\n",
      "train step is : 7800\n",
      "0.9672\n",
      "train step is : 7900\n",
      "0.9639\n",
      "train step is : 8000\n",
      "0.9702\n",
      "train step is : 8100\n",
      "0.9699\n",
      "train step is : 8200\n",
      "0.964\n",
      "train step is : 8300\n",
      "0.9714\n",
      "train step is : 8400\n",
      "0.9698\n",
      "train step is : 8500\n",
      "0.9711\n",
      "train step is : 8600\n",
      "0.9691\n",
      "train step is : 8700\n",
      "0.9679\n",
      "train step is : 8800\n",
      "0.9694\n",
      "train step is : 8900\n",
      "0.9706\n",
      "train step is : 9000\n",
      "0.9718\n",
      "train step is : 9100\n",
      "0.9665\n",
      "train step is : 9200\n",
      "0.968\n",
      "train step is : 9300\n",
      "0.9697\n",
      "train step is : 9400\n",
      "0.9692\n",
      "train step is : 9500\n",
      "0.9726\n",
      "train step is : 9600\n",
      "0.9689\n",
      "train step is : 9700\n",
      "0.9756\n",
      "train step is : 9800\n",
      "0.9737\n",
      "train step is : 9900\n",
      "0.9728\n",
      "train step is : 10000\n",
      "0.975\n",
      "train step is : 10100\n",
      "0.9724\n",
      "train step is : 10200\n",
      "0.9729\n",
      "train step is : 10300\n",
      "0.9722\n",
      "train step is : 10400\n",
      "0.9761\n",
      "train step is : 10500\n",
      "0.9715\n",
      "train step is : 10600\n",
      "0.976\n",
      "train step is : 10700\n",
      "0.974\n",
      "train step is : 10800\n",
      "0.9734\n",
      "train step is : 10900\n",
      "0.9745\n",
      "train step is : 11000\n",
      "0.9742\n",
      "train step is : 11100\n",
      "0.9765\n",
      "train step is : 11200\n",
      "0.9747\n",
      "train step is : 11300\n",
      "0.97\n",
      "train step is : 11400\n",
      "0.9751\n",
      "train step is : 11500\n",
      "0.9727\n",
      "train step is : 11600\n",
      "0.9736\n",
      "train step is : 11700\n",
      "0.9745\n",
      "train step is : 11800\n",
      "0.976\n",
      "train step is : 11900\n",
      "0.9741\n",
      "train step is : 12000\n",
      "0.9737\n",
      "train step is : 12100\n",
      "0.9725\n",
      "train step is : 12200\n",
      "0.9761\n",
      "train step is : 12300\n",
      "0.9779\n",
      "train step is : 12400\n",
      "0.9733\n",
      "train step is : 12500\n",
      "0.9741\n",
      "train step is : 12600\n",
      "0.974\n",
      "train step is : 12700\n",
      "0.9717\n",
      "train step is : 12800\n",
      "0.9743\n",
      "train step is : 12900\n",
      "0.9715\n",
      "train step is : 13000\n",
      "0.9758\n",
      "train step is : 13100\n",
      "0.9741\n",
      "train step is : 13200\n",
      "0.9777\n",
      "train step is : 13300\n",
      "0.977\n",
      "train step is : 13400\n",
      "0.9782\n",
      "train step is : 13500\n",
      "0.9731\n",
      "train step is : 13600\n",
      "0.9779\n",
      "train step is : 13700\n",
      "0.9682\n",
      "train step is : 13800\n",
      "0.9716\n",
      "train step is : 13900\n",
      "0.9791\n",
      "train step is : 14000\n",
      "0.9747\n",
      "train step is : 14100\n",
      "0.9764\n",
      "train step is : 14200\n",
      "0.9786\n",
      "train step is : 14300\n",
      "0.9761\n",
      "train step is : 14400\n",
      "0.9782\n",
      "train step is : 14500\n",
      "0.9773\n",
      "train step is : 14600\n",
      "0.9774\n",
      "train step is : 14700\n",
      "0.978\n",
      "train step is : 14800\n",
      "0.9785\n",
      "train step is : 14900\n",
      "0.9768\n",
      "train step is : 15000\n",
      "0.9801\n",
      "train step is : 15100\n",
      "0.9792\n",
      "train step is : 15200\n",
      "0.9797\n",
      "train step is : 15300\n",
      "0.9797\n",
      "train step is : 15400\n",
      "0.9789\n",
      "train step is : 15500\n",
      "0.9772\n",
      "train step is : 15600\n",
      "0.979\n",
      "train step is : 15700\n",
      "0.978\n",
      "train step is : 15800\n",
      "0.9727\n",
      "train step is : 15900\n",
      "0.9796\n",
      "train step is : 16000\n",
      "0.9775\n",
      "train step is : 16100\n",
      "0.9791\n",
      "train step is : 16200\n",
      "0.9804\n",
      "train step is : 16300\n",
      "0.9725\n",
      "train step is : 16400\n",
      "0.978\n",
      "train step is : 16500\n",
      "0.9764\n",
      "train step is : 16600\n",
      "0.9791\n",
      "train step is : 16700\n",
      "0.9784\n",
      "train step is : 16800\n",
      "0.9785\n",
      "train step is : 16900\n",
      "0.9805\n",
      "train step is : 17000\n",
      "0.9808\n",
      "train step is : 17100\n",
      "0.9818\n",
      "train step is : 17200\n",
      "0.9787\n",
      "train step is : 17300\n",
      "0.9818\n",
      "train step is : 17400\n",
      "0.9776\n",
      "train step is : 17500\n",
      "0.9806\n",
      "train step is : 17600\n",
      "0.9788\n",
      "train step is : 17700\n",
      "0.9813\n",
      "train step is : 17800\n",
      "0.9814\n",
      "train step is : 17900\n",
      "0.9777\n",
      "train step is : 18000\n",
      "0.9779\n",
      "train step is : 18100\n",
      "0.9799\n",
      "train step is : 18200\n",
      "0.9816\n",
      "train step is : 18300\n",
      "0.9795\n",
      "train step is : 18400\n",
      "0.9812\n",
      "train step is : 18500\n",
      "0.9795\n",
      "train step is : 18600\n",
      "0.9803\n",
      "train step is : 18700\n",
      "0.9815\n",
      "train step is : 18800\n",
      "0.9797\n",
      "train step is : 18900\n",
      "0.9804\n",
      "train step is : 19000\n",
      "0.9812\n",
      "train step is : 19100\n",
      "0.9813\n",
      "train step is : 19200\n",
      "0.979\n",
      "train step is : 19300\n",
      "0.9777\n",
      "train step is : 19400\n",
      "0.9802\n",
      "train step is : 19500\n",
      "0.9813\n",
      "train step is : 19600\n",
      "0.9821\n",
      "train step is : 19700\n",
      "0.9793\n",
      "train step is : 19800\n",
      "0.9795\n",
      "train step is : 19900\n",
      "0.9786\n",
      "0.9818\n"
     ]
    }
   ],
   "source": [
    "\n",
    "# 载入数据集\n",
    "mnist = input_data.read_data_sets('MNIST_data', one_hot=True)\n",
    "\n",
    "def max_pool(x):\n",
    "    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding='SAME')\n",
    "\n",
    "x = tf.placeholder(tf.float32, [None, 784])\n",
    "x_image = tf.reshape(x, [-1, 28, 28, 1])\n",
    "\n",
    "k = 4\n",
    "l = 8\n",
    "m = 12\n",
    "n = 16\n",
    "f = 20\n",
    "\n",
    "def get_weight(shape,regularizer): #shape为列表，regularizer为正则化权重\n",
    "    w = tf.Variable(tf.truncated_normal(shape,stddev = 0.1))\n",
    "    tf.add_to_collection('losses',tf.contrib.layers.l2_regularizer(regularizer)(w)) #正则化，来缓解过拟合,将所有计算好的正则化了的 w 加在 losses 赋值在上\n",
    "    return w\n",
    "\n",
    "\n",
    "\n",
    "#W1 = tf.Variable(tf.truncated_normal([5,5,1,k],stddev = 0.1))\n",
    "W1 = get_weight([5,5,1,k],0.01)\n",
    "b1 = tf.Variable(tf.ones([k])/10)\n",
    "\n",
    "#W2 = tf.Variable(tf.truncated_normal([5,5,k,l],stddev = 0.1))\n",
    "W2 = get_weight([5,5,k,l],0.01)\n",
    "b2 = tf.Variable(tf.ones([l])/10)\n",
    "\n",
    "#W3 = tf.Variable(tf.truncated_normal([5,5,l,m],stddev = 0.1))\n",
    "W3 = get_weight([5,5,l,m],0.01)\n",
    "b3 = tf.Variable(tf.ones([m])/10)\n",
    "\n",
    "W4 = get_weight([3,3,m,n],0.01)\n",
    "b4 = tf.Variable(tf.ones([n])/10)\n",
    "\n",
    "W5 = get_weight([1,1,n,f],0.01)\n",
    "b5= tf.Variable(tf.ones([f])/10)\n",
    "\n",
    "t = 200  #n\n",
    "\n",
    "#W4 = tf.Variable(tf.truncated_normal([1*1*m,n],stddev = 0.1))\n",
    "W6 = get_weight([1*1*f,t],0.01)\n",
    "b6 = tf.Variable(tf.ones([t])/10)\n",
    "\n",
    "#W5 = tf.Variable(tf.truncated_normal([n,10],stddev = 0.1))\n",
    "W7 = get_weight([t,10],0.01)\n",
    "b7 = tf.Variable(tf.ones([10])/10)\n",
    "\n",
    "y1 = tf.nn.relu(tf.nn.conv2d(x_image,W1,strides=[1,1,1,1],padding = 'SAME')+b1)\n",
    "print(\"y1.shape\")\n",
    "print(y1.shape)\n",
    "y1 = max_pool(y1)\n",
    "print(y1.shape)\n",
    "\n",
    "y2 = tf.nn.relu(tf.nn.conv2d(y1,W2,strides=[1,1,1,1],padding = 'SAME')+b2)\n",
    "print(\"y2.shape\")\n",
    "print(y2.shape)\n",
    "y2 = max_pool(y2)\n",
    "print(y2.shape)\n",
    "\n",
    "y3 = tf.nn.relu(tf.nn.conv2d(y2,W3,strides=[1,1,1,1],padding = 'SAME')+b3)\n",
    "print(\"y3.shape\")\n",
    "print(y3.shape)\n",
    "y3 = max_pool(y3)\n",
    "print(y3.shape)\n",
    "\n",
    "y4 = tf.nn.relu(tf.nn.conv2d(y3,W4,strides=[1,1,1,1],padding = 'SAME')+b4)\n",
    "print(\"y4.shape\")\n",
    "print(y4.shape)\n",
    "y4 = max_pool(y4)\n",
    "print(y4.shape)\n",
    "\n",
    "y5 = tf.nn.relu(tf.nn.conv2d(y4,W5,strides=[1,1,1,1],padding = 'SAME')+b5)\n",
    "print(\"y5.shape\")\n",
    "print(y5.shape)\n",
    "y5 = max_pool(y5)\n",
    "print(y5.shape)\n",
    "\n",
    "yy = tf.reshape(y5,shape=[-1,1*1*f])\n",
    "\n",
    "y6 = tf.nn.relu(tf.matmul(yy,W6)+b6)\n",
    "print(y6.shape)\n",
    "\n",
    "y = tf.nn.softmax(tf.matmul(y6, W7) + b7)\n",
    "print(y.shape)\n",
    "\n",
    "# 为了计算交叉熵，我们首先需要添加一个新的占位符用于输入正确值\n",
    "y_ = tf.placeholder(\"float\", [None, 10])\n",
    "\n",
    "# 交叉熵损失函数\n",
    "cross_entropy = -tf.reduce_sum(y_*tf.log(y))\n",
    "cross_function = cross_entropy + tf.add_n(tf.get_collection('losses'))\n",
    "\n",
    "#训练方法，学习率为1e-4\n",
    "train_step = tf.train.GradientDescentOptimizer(1e-4).minimize(cross_function)\n",
    "\n",
    "#初始化变量\n",
    "init = tf.global_variables_initializer()\n",
    "\n",
    "sess = tf.Session()\n",
    "sess.run(init)\n",
    "\n",
    "# 开始训练模型,循环训练1000次\n",
    "for i in range(20000):\n",
    "    # 随机抓取训练数据中的100个批处理数据点\n",
    "    batch_xs, batch_ys = mnist.train.next_batch(100)\n",
    "\n",
    "    # 喂入数据，开始训练\n",
    "    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})\n",
    "    if(i%100 == 0):\n",
    "        print(\"train step is : \"+str(i))\n",
    "        #计算正确率\n",
    "        correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))\n",
    "        accuracy = tf.reduce_mean(tf.cast(correct_prediction, \"float\"))\n",
    "        print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))\n",
    "    \n",
    "\n",
    "# 检验真实标签与预测标签是否一致\n",
    "correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))\n",
    "# 计算精确度，将true和false转化成相应的浮点数，求和取平均\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_prediction, \"float\"))\n",
    "# 计算所学习到的模型在测试数据集上面的正确率\n",
    "print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
